﻿// Bla fasel

public namespace OtherTest
{
	public namespace Nested
	{
	}
}

public namespace OtherTest.Nested
{
}

public namespace OtherTest.Nested.Detailed
{
	using MyTest.MySecond as Zweites;
	using MyTest;
	using OtherTest.Nested as Foo;
	
	public abstract class Test1 : MyClass
	{
		public abstract function AbstractFunc(int x) -> int;
	}
	
	public class Test2 : Zweites.InSecond
	{
	}
}

public namespace MyTest
{ 
	/// My first class
	public class MyClass
	{
		public ctor(string name)
		  : super("Default")
		{
			this.Name = name;
			Age = 18;
		}
		
		public var MyList = [1,2,3,2];
		public var list<float> MyFloatList = [1,2,3,2];
		public var float MyFloat = 3 * 3;
		
		public function pain()
		{
		}
	
		public function printLn(string str)
		{
		}
			
		/// <summary>Some function<summary>
		public function foo( int x, int y ) -> float
		{
			var int x = 5;
			var z = 23;
			var s = { "torben" : 1973, "claudia" : 1977 };
			var flist = new list<float>[ 1, 2, 3 ];
			var list<int> lst = [1,2,3,5];
			var list<int> lst2 = map( lst, m -> m*2 );
			var int result = reduce( lst, function(int a, int b) -> int { return a * b; }, 1 );
			var int result2 = reduce( lst, a b -> a * b, 1 );
			var list<int> clist;
			var n = new MyClass("Hallo Welt");
			var dict<string,MyClass> mydict;
			
			if ( x == 12 )
			{
				printLn("Hello 12");
			}
			else if ( x == y )
			{
				printLn("Gleich");
			}
			else
			{
				printLn("Rest");
			}
			
			for( var j = 0; j < 10; ++j )
			{
				printLn("Loop" + j.toString());
				x++;
			}
			
			foreach( var int i in lst )
			{
				printLn(i.toString());
			}
			foreach( var float i in lst )
			{
				printLn(i.toString());
			}
			foreach( var i in lst )
			{
				i = i * 2;
			}
			foreach( var s in ["A", "B", "C"])
			{
				var string s2 = s;
			}

			while( true )
			{
			}
			
			var a = 4;
			do
			{				
				var string x = (a++).toString();
			} while ( x < 10 );
			
			switch( a )
			{
				case 45:
					print("45");
					break;
				case 3:
					print("small");
					break;
				default:
					break;
			}
			
			throw "Hallo";
			
			try
			{
				fuckedup();
			}
			catch( var MyException ex )
			{
			}
			finally
			{
			}
		}
		
		private var string Name;
		
		public property string Surname { get; private set { this.Name = value; } }

		public property int Age
		{
			get
			{
				var int x = 0;
				return 42;
			}
			set
			{
				this.Name = "Alter Mann von " + value.toString() + " Jahren";
			}
		}
				
		public static var MaxVal = 1000 + 3 * 2;
	}
	
	public class Second : MyClass
	{
		public static function print(string str)
		{
			super.foo(100,200);
		}
		
		public function bar() -> bool
		{
			pain();
			return false;
		}
		
		public var MyClass dumm = new MyClass("funny");
		public var function(int) -> bool onMouseDown;
		public var void -> bool onMouseDown2;
		public var Second -> void onExit;
		public var function() onClose;
		
		public static function staticFoo( int x, int y ) -> float
		{
			print("Hallo");
		}
		
		public override function foo( int x, int y ) -> float
		{
			this.onMouseDown = i -> (i==3);
			this.onMouseDown = function(int i) -> bool { print("Doof"); return i==3; };
			if ( x is int )
			{
				print("Int");
			}
			var z = x as MyClass;
			x = x * y;
		}
		
		var x = 123;
		print("Some static text" + x.toString());
		var function(int,int) -> float funcy = staticFoo;
	}
}

public namespace MyTest.MySecond
{
	public class TestMe : list<int>
	{
	}
	
	public class InSecond
	{
		public function display( int x )
		{
		}
		
		public function display( float f )
		{
		}
		
		public function display( string str )
		{
		}
		
		public function display( object obj)
		{
		}
		
		public function test()
		{
			display(2);
			display(3.5);
			display("Hallo");
			display( new InSecond() );
		}
	}
	
	public interface I1
	{
		public abstract function Y(int i);
		public abstract property float P { get; set; }
	}
	
	public interface I2 : I1
	{
		public abstract function Z(int i) -> bool;	
	}
	
	public interface K1
	{
		public abstract property int X { get; }
		public abstract property int P2 { get; }
	}
	
	public abstract class A : I2
	{
		public abstract function Y(int i);
		public function Z(int i) -> bool { }		
		public abstract property float P { get; set; }
		public static function Foo() { }
	}
	
	public class B : A, K1
	{
		public override function Y(int i) { }
		public override function Z(int i) -> bool { }
		public property int X { get; }
		public property int P2 { get; }
		public static function Foo(string s) { }
		public function Z(string s) -> bool
		{
			this.Z( 4 );
			this.Z( "Hui" );
		}
		
		public override property float P { get; set; }
	}
	
	public class MyTemplate<T,V> : InSecond where T : I1, V : I2, T : ctor()
	{
		public function Set(V v, T t)
		{
			var list<V> lst;
			var MyTemplate<int,float> sometemplate;
		}
	}

	public class MyTemplate<T> : InSecond where T : I1, T : ctor()
	{
		public function FooBar(T t)
		{
			var MyTemplate<int> othertemplate;
		}
	}
	
	public class C
	{
		public ctor()
		{
		}
		
		public ctor(string Name)
		{
		}
	}
}

var f = 4.2;
f = 7;
var n = new MyTest.MyClass("Neue Klasse");
n = null;
var cmp = null == n;
n.foo(1,2);
var object f2 = MyTest.Second.print;
var c = new MyTest.MySecond.C();
var c2 = new MyTest.MySecond.C("Hallo Welt");
var bool mybool = !true;
var i = 5;
i++;

// var xml = <div style="foo">Wunderbare<span>Hallo Eingabe \+ Neues<input /><button /><span style={foo()}></span></span>Welt<x>doof</x></div>;
// var xml2 = <div>{foo()}</div>;
// var xml3 = <div>{foo()}<span>{foo()}</span>{foo()}</div>;
// var xml4 = <button onclick={a -> print(a)}/>;

//wait for receive(MyMessageType) | timeout(2000);

//wait for receive(MyMessageType t)
//{
//	print(t);
//}
//| timeout(5000)
//{
//	print("Timeout");
//};

//var w = receive(V v) { print(v); };
//var x = timeout(1000);
//wait for w | x;

//var signal<T> sig = new signal<T>();
//wait for receive(T t) from sig;
//wait for receive(T t) from sig
//{
//	print(t);
//};

//wait for receive(T t) from sig where t -> t.Name == "Torben"
//{
//};